/**
 * Created by Ysssssss on 21/2/26.
 */

import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import {Spin, Upload} from 'antd';
import ImgCrop from 'antd-img-crop';
import notify from "@utils/tip";
// import { uploadQiniuFile } from '@utils/qiniu'
import { uploadCOSFile } from '@utils/cos'
import {EyeOutlined} from "@ant-design/icons";
import BilinIcon from "@common/presentational/BilinIcon";

const reformedFileList = (value) =>
    Array.isArray(value) ? value.map((item, index) => ({
        uid: -(index + 1),
        status: 'done',
        url: item,
    })) : (value ? [{
        uid: '-1',
        status: 'done',
        url: value,
    }] : [])

class ImageUpload extends PureComponent {
    static propTypes = {
        value: PropTypes.oneOfType([
            PropTypes.string,
            PropTypes.array,
        ]),
        onChange: PropTypes.func,
        needCrop: PropTypes.bool,
        maxFileSize: PropTypes.string,
        maxVideoSize: PropTypes.string,
        aspectRatio: PropTypes.number,
        maxLength: PropTypes.number,
        accept: PropTypes.string,
        listType: PropTypes.string,
        uploadIntro: PropTypes.node,
        className: PropTypes.string,
        disabled: PropTypes.bool
    }

    static defaultProps = {
        value: '',
        onChange: () => {},
        needCrop: false,
        maxFileSize: '500kb',
        maxVideoSize: '5m',
        aspectRatio: 1,
        maxLength: 1,
        accept: 'image/png, image/jpeg, image/jpg, image/gif',
        listType: 'picture-card',
    }

    constructor(props) {
        super(props);
        const { value } = props

        this.state = {
            fileList: reformedFileList(value),
            isUploading: false
        }

        this.uploadAction = this.uploadAction.bind(this)
        this.beforeUpload = this.beforeUpload.bind(this)
        this.beforeCrop = this.beforeCrop.bind(this)
        this.itemRender = this.itemRender.bind(this)
        this.removeFile = this.removeFile.bind(this)
    }

    static getDerivedStateFromProps (props, state) {
        const { value } = props
        return {
            fileList: reformedFileList(value),
            isUploading: state.isUploading ? state.fileList.length >= props.value.length : false
        }
    }

    getMaxFileSize (maxFileSize) {
        if (!maxFileSize) return 500*1024
        const unit = maxFileSize.replace(/[^a-zA-Z]/g,'').toLowerCase()
        const count = maxFileSize.replace(/[^\d]/g,'') - 0
        switch (unit) {
            case 'b':
                return count
            case 'kb':
            case 'k':
                return count * 1024
            case 'mb':
            case 'm':
                return count * 1024 * 1024
            case 'gb':
            case 'g':
                return count * 1024 * 1024 * 1024
        }
        return 500*1024
    }

    beforeCrop (file) {
        if (file.type.includes('mp4')) {
            this.beforeUpload(file) && this.uploadAction(file)
            return false
        }
        return true
    }

    beforeUpload (file) {
        const { maxFileSize, maxVideoSize } = this.props
        const _fileSize = file.size;
        if (file.type.includes('mp4') && _fileSize - this.getMaxFileSize(maxVideoSize) >= 0) {
            notify('视频大小不能超过'+maxVideoSize, 'error')
            return false
        }
        if (!file.type.includes('mp4') && _fileSize - this.getMaxFileSize(maxFileSize) >= 0) {
            notify('图片大小不能超过'+maxFileSize, 'error')
            return false
        }
        return true
    }

    uploadAction (file) {
        const { value, maxLength } = this.props
        const _this = this
        return new Promise(resolve => {
            let uploadFunc = uploadCOSFile // uploadQiniuFile
            if (file.type.includes('mp4')) {
                this.setState({
                    isUploading: true
                })
                uploadFunc(file, 'image', file.type.replace('video/', ''), res => {
                    _this.props.onChange(maxLength === 1 ? res.key : [...value, res.key])
                    resolve()
                }, () => {
                    this.setState({
                        isUploading: false
                    })
                    resolve()
                })
            } else {
                const reader = new FileReader();
                reader.readAsArrayBuffer(file);
                reader.onload = (e) => {
                    const result = e.target.result
                    let blob = null;
                    if (typeof result === 'object') {
                        blob = new Blob([result])
                    } else {
                        blob = result
                    }
                    this.setState({
                        isUploading: true
                    })
                    let uploadFunc = uploadCOSFile // uploadQiniuFile
                    uploadFunc(blob, 'image', file.type.replace('image/', ''), res => {
                        _this.props.onChange(maxLength === 1 ? res.key : [...value, res.key])
                        resolve()
                    }, () => {
                        this.setState({
                            isUploading: false
                        })
                        resolve()
                    })
                }
            }
        })
    }

    itemRender (originNode, file, fileList) {
        return (
            <div className="upload-preview-box">
                { file.url.includes('.mp4') ? (
                    <video src={file.url} muted autoPlay/>
                ) : (
                    <img src={file.url} alt=""/>
                ) }
                <div className="upload-operation-cover">
                    <a href={file.url} target="_blank">
                        <EyeOutlined className="operation-icon clr-fff"/>
                    </a>
                    <BilinIcon className="operation-icon" type="design-delete" onClick={this.removeFile.bind(this, file.uid)}/>
                </div>
            </div>
        )
    }

    removeFile (uid) {
        const { value, maxLength } = this.props
        const index = -uid - 1

        this.props.onChange(maxLength === 1 ? '' : [
            ...value.slice(0, index),
            ...value.slice(index + 1)
        ])
    }


    render () {
        const { needCrop, listType, accept, maxLength, aspectRatio, maxFileSize, maxVideoSize, uploadIntro, disabled, className } = this.props
        const { isUploading, fileList } = this.state
        const uploadNode = (
            <Upload
                action={this.uploadAction}
                accept={accept}
                customRequest={() => {}}
                fileList={fileList}
                listType={listType}
                beforeUpload={this.beforeUpload}
                className={className ? 'custom-upload-container ' + className : 'custom-upload-container'}
                disabled={isUploading || disabled}
                itemRender={this.itemRender}
            >
                { isUploading ? (<Spin />) : (fileList.length >= maxLength ? null : <BilinIcon type="plus" className="ft-24 ft-clr-ml"/>) }
            </Upload>
        )
        return (
            <div className="flex">
                { needCrop ? (
                    <ImgCrop
                        aspect={aspectRatio}
                        modalTitle="图片上传"
                        fillColor="transparent"
                        beforeCrop={this.beforeCrop}
                    >
                        { uploadNode }
                    </ImgCrop>
                ) : uploadNode }
                { uploadIntro !== undefined ? uploadIntro : (
                    <div className="custom-upload-intro ft-12 ft-clr-ml mgl-24">
                        <p>支持格式：{ accept.split(',').map(item => item.split('/')[1]).join(', ') }</p>
                        { accept.includes('video') ? (
                            <>
                                <p>图片文件大小：{ maxFileSize }</p>
                                <p>视频文件大小：{ maxVideoSize }</p>
                            </>
                        ) : (
                            <p>文件大小：{ maxFileSize }</p>
                        ) }
                    </div>
                ) }
            </div>
        )
    }
}

export default ImageUpload